package com.youdianda.service.impl;

import com.alibaba.fastjson.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.youdianda.constant.MessageConstant;
import com.youdianda.context.BaseContext;
import com.youdianda.dto.LoginDto;
import com.youdianda.dto.SysUserInsertDTO;
import com.youdianda.dto.SysUserPageDTO;
import com.youdianda.dto.UserUpdateDTO;
import com.youdianda.entity.SysConfig;
import com.youdianda.entity.SysMenu;
import com.youdianda.entity.SysRole;
import com.youdianda.entity.SysUser;
import com.youdianda.entity.*;

import com.youdianda.mapper.SysDictMapper;
import com.youdianda.mapper.SysRoleMapper;
import com.youdianda.mapper.SysUserMapper;
import com.youdianda.result.Result;
import com.youdianda.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youdianda.utils.JwtUtil;
import com.youdianda.vo.*;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author sdy
 * @since 2023-05-15
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {


    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private ISysMenuService sysMenuService;

    @Autowired
    private SysDictMapper sysDictMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private IYddCateService yddCateService;

    @Autowired
    private IYddAdvposService yddAdvposService;

    @Autowired
    private IYddTagService yddTagService;

    @Autowired
    private IYddArticleService yddArticleService;

    @Autowired
    private IYddAdvimgService yddAdvimgService;

    @Autowired
    private IYddUserService yddUserService;





    /**
     * 获取系统配置
     *
     * @return
     */
    @Override
    public Result<GetConfigVo> getConfig() {

        LambdaQueryWrapper<SysConfig> queryWrapper = Wrappers.lambdaQuery();
        //1.查询数据
        String loginTitle = "login_title";
        String login_title = sysConfigService.getOne(queryWrapper.eq(SysConfig::getAttrKey, loginTitle)).getAttrValue();

        String loginBg = "login_bg";
        String login_bg = sysConfigService.getOne(queryWrapper.eq(SysConfig::getAttrKey, loginBg)).getAttrValue();

        String systemName = "system_name";
        String system_name = sysConfigService.getOne(queryWrapper.eq(SysConfig::getAttrKey, systemName)).getAttrValue();

        String systemLogo = "system_logo";
        String system_logo = sysConfigService.getOne(queryWrapper.eq(SysConfig::getAttrKey, systemLogo)).getAttrValue();

        String webIco = "web_ico";
        String web_ico = sysConfigService.getOne(queryWrapper.eq(SysConfig::getAttrKey, webIco)).getAttrValue();

        //2.封装数据
        GetConfigVo vo = GetConfigVo.builder()
                .login_title(login_title)
                .login_bg(login_bg)
                .system_name(system_name)
                .system_logo(system_logo)
                .web_ico(web_ico)
                .build();

        return Result.success(vo);
    }

    /**
     * 主页统计信息
     *
     * @return
     */
    @Override
    public Result<BaseInfoVO> baseInfo() {

        //1.查询数据
        List<YddCate> allCate = yddCateService.list();//所有分类数据
        ArrayList<AllCateVO> cateVOS = new ArrayList<>();
        allCate.forEach(cate->{
            AllCateVO allCateVO = new AllCateVO();
            BeanUtils.copyProperties(cate,allCateVO);
            allCateVO.setNum(cate.getSortNum());
            cateVOS.add(allCateVO);
        });

        Long advposNum = yddAdvposService.count();//广告位总数
        Long tagNum = yddTagService.count();//标签总数
        Long adminNum = sysRoleService.count();//管理员总数
        Long articleNum = yddArticleService.count();//文章总数
        Long cateNum = yddCateService.count();//分类总数
        Long advimgNum = yddAdvimgService.count();//广告图总数

        //最新用户数据
        ArrayList<NewUserVO> newUser = new ArrayList<>();


        Stream<YddUser> usersList = yddUserService.list(Wrappers.<YddUser>lambdaQuery().orderByDesc(YddUser::getId)).stream().limit(7);
        usersList.forEach(user->{
            NewUserVO userVO = new NewUserVO();
            BeanUtils.copyProperties(user,userVO);
            newUser.add(userVO);
        });

        //热门文章数据
        ArrayList<HotArticleVO> hotArticle = new ArrayList<>();
        List<YddArticle> yddArticleList = yddArticleService.list();
        yddArticleList.forEach(yddArticle -> {
            HotArticleVO hotArticleVO = new HotArticleVO();
            BeanUtils.copyProperties(yddArticle, hotArticleVO);
            hotArticle.add(hotArticleVO);
        });

        UserVO user = UserVO.builder()
                .total(Integer.parseInt(yddUserService.count() + ""))
                .user_woman(Integer.parseInt(yddUserService.count(Wrappers.<YddUser>lambdaQuery().eq(YddUser::getSex, 1)) + ""))
                .user_man(Integer.parseInt(yddUserService.count(Wrappers.<YddUser>lambdaQuery().eq(YddUser::getSex, 0)) + ""))
                .build();

        BaseInfoVO vo = BaseInfoVO.builder()
                .all_cate(cateVOS)
                .advpos_num(Integer.parseInt(advposNum + ""))
                .tag_num(Integer.parseInt(tagNum + ""))
                .admin_num(Integer.parseInt(adminNum + ""))
                .article_num(Integer.parseInt(articleNum + ""))
                .cate_num(Integer.parseInt(cateNum + ""))
                .advimg_num(Integer.parseInt(advimgNum + ""))
                .new_user(newUser)
                .hot_article(hotArticle)
                .user(user)
                .build();

        return Result.success(vo);
    }

    /**
     * 登录接口
     *
     * @param loginDto
     * @return
     */
    @Override
    public Result login(LoginDto loginDto) {

        //1.判断用户是否存在
        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
        SysUser sysUser = getOne(queryWrapper.eq(SysUser::getLoginName, loginDto.getLoginName()));

        if (sysUser == null) {
            return Result.error(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //2.判断密码是否正确
        if (!sysUser.getPassword().equals(DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes()))) {
            return Result.error(MessageConstant.PASSWORD_ERROR);
        }

        //3.生成token

        Token token = Token.builder().token(JwtUtil.getToken(Long.parseLong(sysUser.getId()))).build();

        //4.返回数据

        return Result.success(token);
    }

    /**
     * 获取用户资料
     *
     * @return
     */
    @Override
    public Result<ProfileVO> profile() {

        //1.获取用户资料
        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
        SysUser sysUser = getOne(queryWrapper.eq(SysUser::getId, BaseContext.getCurrentId()));

        System.out.printf("+++++++++++++++++++++++++++++++", BaseContext.getCurrentId());

        //========================================================================================================
        //查询管理员名称
        String roleId = sysUser.getRoleId();
        int length = roleId.length();
        String substring = roleId.substring(2, length - 2);

        List<String> list5 = Arrays.asList(substring);

        String s = list5.get(0);
        String roleName = sysRoleService.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getId, s)).getName();
        //========================================================================================================

        //用户资料
        UserInfoVO userInfo = new UserInfoVO();
        BeanUtils.copyProperties(sysUser, userInfo);
        userInfo.setRolename(roleName);
        System.out.println(userInfo);

        //2.用户菜单权限
        List<SysMenu> menuList = sysMenuService.list(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getType, 1));

        //3.dictList
        String interfaceType = "interface_type";
        List<TypeVO> typeList = sysDictMapper.selectMap(interfaceType);
        ArrayList<Object> list = new ArrayList<>();
        typeList.forEach(typeVO -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(typeVO.getValue(), typeVO.getLabel());
            list.add(jsonObject);
        });


        String orderType = "order_type";
        List<TypeVO> typeList1 = sysDictMapper.selectMap(orderType);
        ArrayList<Object> list1 = new ArrayList<>();
        typeList1.forEach(typeVO -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(typeVO.getValue(), typeVO.getLabel());
            list1.add(jsonObject);
        });

        String reportType = "report_type";
        List<TypeVO> typeList2 = sysDictMapper.selectMap(reportType);
        ArrayList<Object> list2 = new ArrayList<>();
        typeList2.forEach(typeVO -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(typeVO.getValue(), typeVO.getLabel());
            list2.add(jsonObject);
        });

        String tableType = "table_type";
        List<TypeVO> typeList3 = sysDictMapper.selectMap(tableType);
        ArrayList<Object> list3 = new ArrayList<>();
        typeList3.forEach(typeVO -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(typeVO.getValue(), typeVO.getLabel());
            list3.add(jsonObject);
        });

        String theme = "theme";
        List<TypeVO> typeList4 = sysDictMapper.selectMap(theme);
        ArrayList<Object> list4 = new ArrayList<>();
        typeList4.forEach(typeVO -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(typeVO.getValue(), typeVO.getLabel());
            list4.add(jsonObject);
        });


        DictsListVO dictList = DictsListVO.builder()
                .interface_type(list)
                .order_type(orderType)
                .report_type(reportType)
                .table_type(tableType)
                .theme(theme)
                .build();
        System.out.println(dictList);
        //btnList

        ProfileVO vo = ProfileVO.builder()
                .userInfo(userInfo)
                .menuList(menuList)
                .dictsList(dictList)
                .btnList(Arrays.asList("*"))
                .build();

        return Result.success(vo);
    }

    /**
     * 用户列表 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public Result userList(SysUserPageDTO dto) {
       /* //创建分页
        IPage<SysUser> rolePage = new Page<>(Integer.parseInt(dto.getPage()), Integer.parseInt(dto.getLimit()));
        //启动分页 模糊查询
        LambdaQueryWrapper<SysUser> like = Wrappers.<SysUser>lambdaQuery()
                .like(dto.getLoginName() != null && dto.getLoginName() != "", SysUser::getName, dto.getLoginName())
                .like(dto.getPhone() != null && dto.getPhone() != "", SysUser::getPhone, dto.getPhone())
                .like(dto.getStatus() != null && dto.getStatus() != "", SysUser::getStatus, dto.getStatus());
        IPage<SysUser> page = page(rolePage, like);

        //遍历集合查询将查询的数据进行封装到dto里面  获取名字  获取roleId集合
        List<String> roleID = new ArrayList<>();
        List<String>roleName=new ArrayList<>();
        List<SysUser> records = page.getRecords();
        //创建一个集合用来保存对象转换后的数据
        List<SysUserDateVO> newList= new ArrayList<>();
        for (SysUser record : records) {
            //遍历集合中的元素 获取名字
            String roleId = record.getRoleId();
            //创建一个数组
            String[] arr =new String[3];

            //进行判断 看看这个roleId是否包含逗号 是否是有多个参数
            if (roleId.contains(",")) {
                //进行切割 将数据存放到数组中
                arr = roleId.split(",");
                //遍历这个数组
                for (int i = 0; i < arr.length; i++) {
                    //获取对应role角色表中的名字
                    SysRole byId = sysRoleMapper.selectById(arr[i]);
                    roleName.add(byId.getName());
                    roleID.add(arr[i]);
                }
                record.setRolename(roleName);
            }else {
                roleID.add(roleId);
                SysRole sysRole = sysRoleMapper.selectById(roleId);
                record.setRolename(Arrays.asList(sysRole.getName()));
            }

            //创建一个对象进行对象copy
            SysUserDateVO sysUserDateVO = new SysUserDateVO();
            BeanUtils.copyProperties(record,sysUserDateVO);
            sysUserDateVO.setRoleId(roleID);
            newList.add(sysUserDateVO);
        }

    //封装数据
    SysUserPageVO build = SysUserPageVO.builder()
            .pageSize(page.getSize())
            .data(newList)
            .count(page.getPages())
            .totalPages(page.getTotal())
            .currentPage(page.getCurrent())
            .build();
        return Result.success(build);*/
//----------------------------------------------------------------------------------------------------------------------
        //创建分页
        IPage<SysUser> rolePage = new Page<>(Integer.parseInt(dto.getPage()), Integer.parseInt(dto.getLimit()));
        //启动分页 模糊查询
        LambdaQueryWrapper<SysUser> like = Wrappers.<SysUser>lambdaQuery()
                .like(dto.getLogin_name() != null && dto.getLogin_name() != "", SysUser::getLoginName, dto.getLogin_name())
                .like(dto.getPhone() != null && dto.getPhone() != "", SysUser::getPhone, dto.getPhone())
                .like(dto.getStatus() != null && dto.getStatus() != "", SysUser::getStatus, dto.getStatus());
        IPage<SysUser> page = page(rolePage, like);

        //获取元素集合中的roleId字符串
        //创建一个集合用来返回给前端
        List<SysUserDateVO> listVo = new ArrayList<>();
        List<SysUser> records = page.getRecords();
        for (SysUser record : records) {
            String roleId = record.getRoleId();
            //创建一个集合用来存放每一个元素的角色
            List<String> nameList = new ArrayList<>();
            //创建一个集合用来存放每一个元素的roleId
            List<String> roleIdVO = new ArrayList<>();
            //将字符串的中括号和 逗号去掉
            int length = roleId.length();
            String newRoleId = roleId.substring(2, length - 2);
            if (newRoleId.contains(",")) {
                //如果有逗号说明 有多个参数  需要进行切割
                String[] arr = newRoleId.split(",");
                //遍历这个集合  获取对应的角色 以及对应的roleId 并且进行添加到集合中
                for (String s : arr) {
                    SysRole sysRoleName = sysRoleMapper.selectById(s);
                    nameList.add(sysRoleName.getName());
                    roleIdVO.add(s);//存放roleId
                }
                record.setRolename(nameList); //存放角色
            } else {
                //如果不包含逗号 则直接根据这个id查询对应的角色
                SysRole sysRole = sysRoleMapper.selectById(newRoleId);
                String name = sysRole.getName();
                List<String> list = Arrays.asList(name);
                record.setRolename(list); //存放角色
                roleIdVO.add(newRoleId);//存放roleId
            }
            //创建一个对象 将本次运行完毕的对象进行copy以及coleId集合的set
            SysUserDateVO sysUserDateVO = new SysUserDateVO();
            BeanUtils.copyProperties(record, sysUserDateVO);
            sysUserDateVO.setRoleId(roleIdVO);
            listVo.add(sysUserDateVO);
        }
        //封装数据
        SysUserPageVO vo = SysUserPageVO.builder()
                .pageSize(page.getSize())
                .data(listVo)
                .count(page.getPages())
                .totalPages(page.getTotal())
                .currentPage(page.getCurrent())
                .build();
        return Result.success(vo);
    }

    /**
     * 根据id删除用户 管理员删除
     *
     * @param id
     * @return
     */
    @Override
    public Result userDel(String id) {
        //根据id获取user表中的role_id
        SysUser one = getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getId, id));
        //根据role_id干掉对应的role表中的数据
        String roleId = one.getRoleId();
        if (roleId.contains(",")) {
            String[] arr = new String[3];
            arr = roleId.split(",");
            for (String s : arr) {
                sysRoleMapper.deleteById(s);
            }
        }
        sysRoleMapper.deleteById(roleId);
        //删除掉user表中的数据
        removeById(id);
        return Result.success();
    }

    /**
     * 新增员工
     *
     * @param dto
     * @return
     */
    @Override
    public Result userAdd(SysUserInsertDTO dto) {
        //获取数据 copy
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto, sysUser);
        //创建时间
        sysUser.setCreateDate(LocalDateTime.now());
        List<String> roleId = dto.getRoleId();
        //获取对象中的roleid 遍历集合 将集合中的元素就行拼接成一个字符串
        String newRoleId = "[\"";
        for (int i = 0; i < roleId.size(); i++) {
            if (i == roleId.size() - 1) {
                newRoleId = newRoleId + roleId.get(i) + "\"]";
            } else {
                newRoleId = newRoleId + roleId.get(i) + ",";
            }
        }
        sysUser.setRoleId(newRoleId);
        save(sysUser);

        return Result.success();
    }

    /**
     * 根据id查询用户 回显
     *
     * @param id
     * @return
     */
    @Override
    public Result userRowInfo(String id) {
        SysUser byId = getById(id);
        String roleId1 = byId.getRoleId();
        int length = roleId1.length();
        String substring = roleId1.substring(2, length - 2);
        SysUserDateVO sysUserDateVO = new SysUserDateVO();
        BeanUtils.copyProperties(byId, sysUserDateVO);
        if (substring.contains(",")) {
            String[] split = substring.split(",");
            sysUserDateVO.setRoleId(Arrays.asList(split));
        }  else {
            List<String> list = Collections.singletonList(substring);
                sysUserDateVO.setRoleId(list);
        }
        return Result.success(sysUserDateVO);
    }

    /**
     * 根据信息修改数据
     *
     * @param dto
     * @return
     */
    @Override
    public Result userUpdate(UserUpdateDTO dto) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto,sysUser);
        String[] arr = dto.getRoleId();
        List<String> roleId = Arrays.asList(arr);
        String newRoleId = "[\"";
            for (int i = 0; i < roleId.size(); i++) {
                if (i == roleId.size() - 1) {
                    newRoleId = newRoleId + roleId.get(i) + "\"]";
                } else {
                    newRoleId = newRoleId + roleId.get(i) + ",";
                }
            }
        sysUser.setRoleId(newRoleId);
            updateById(sysUser);
        return Result.success();
    }
}
